# -*- coding:utf8 -*-
import numpy as np

# 逻辑与
samples_and = [
    [0, 0, 0],
    [0, 1, 0],
    [1, 0, 0],
    [1, 1, 1]
]

# 逻辑或
samples_or = [
    [0, 0, 0],
    [0, 1, 1],
    [1, 0, 1],
    [1, 1, 1]
]

# 逻辑异或
samples_xor = [
    [0, 0, 0],
    [0, 1, 1],
    [1, 0, 1],
    [1, 1, 0]
]


def perceptron(samples, try_times=10):
    """
    感知器
    :param samples: 逻辑运算数组
    :param try_times: 步进次数
    :return:
    """
    w = np.array([1, 2])
    b = 0
    a = 1

    last_w = None
    last_b = None

    all_t = np.array(samples)[:, 2]

    for i in range(try_times):
        temp_y_list = []
        for j in range(4):
            x = np.array(samples[j][:2])
            y = 1 if np.dot(w, x) + b > 0 else 0
            t = np.array(samples[j][2])

            temp_y_list.append(y)

            delta_b = a * (t - y)
            delta_w = a * (t - y) * x

            print("epoch {} sample {} [{} {} {} {} {} {} {}]".format(
                i, j, w[0], w[1], b, y, delta_w[0], delta_w[1], delta_b
            ))

            w = w + delta_w
            b = b + delta_b

        all_y = np.array(temp_y_list)

        if (last_w is not None) and (last_w == w).all() and (last_b == b):
            if (all_t == all_y).all():
                print("【over, result has been found】")
            else:
                print("【over, nothing has been found】")
            break
        else:
            last_w = w
            last_b = b


if __name__ == "__main__":
    print("logic and")
    perceptron(samples_and)

    print("\nlogic or")
    perceptron(samples_or)

    print("\nlogic xor")
    perceptron(samples_xor, 20)
